Sure is a good thing I found this: http://crypto.stackexchange.com/questions/12621/why-does-openssl-append-extra-bytes-when-encrypting-with-aes-128-ecb. It turns out that openssl doesn't do what you'd think it would do. For one, without the -nopad argument, it always pads, even if that means adding an entire extra block of padding. For two, the -a argument doesn't seem to get applied before checking whether or not the number of input bytes is compatible with the blocksize and keylength.
In [ ]:
function stringToBytes(X::String)
return [UInt8(X[ii]) for ii in 1:length(X)]
end;
function decryptAES128ECBWithKey(ciphertext::String, key::String)
decrypt = chomp(
readstring(
pipeline(`echo -n $ciphertext`,
`base64 --decode`,
`openssl enc -nopad -d -aes-128-ecb -K $key`,
`base64`)))
return decrypt
end
# takes bytes and returns bytes
function decryptAES128ECBWithKey(cipherbytes::Array{UInt8,1}, keybytes::Array{UInt8,1})
ciphertext = base64encode(cipherbytes)
keytext = bytes2hex(keybytes)
return base64decode(decryptAES128ECBWithKey(ciphertext, keytext))
end
function encryptAES128ECBWithKey(plaintext::String, key::String)
encrypt = chomp(
readstring(
pipeline(`echo -n $plaintext`,
`base64 --decode`,
`openssl enc -nopad -e -aes-128-ecb -K $key`,
`base64`)))
return encrypt
end
function encryptAES128ECBWithKey(plaintextbytes::Array{UInt8,1}, keybytes::Array{UInt8,1})
plaintext = base64encode(plaintextbytes)
keytext = bytes2hex(keybytes)
return base64decode(encryptAES128ECBWithKey(plaintext, keytext))
end
function padToNBytes(a::Array{UInt8,1}, nbytes)
newa = Array{UInt8,1}(nbytes)
ntopad = nbytes - length(a)
newa[1:length(a)] = a
newa[(length(a)+1):nbytes] = UInt8(ntopad)
return newa
end;
In [ ]:
pt = "im a 16 byte txt"
ptbytes = stringToBytes(pt)
ptb64 = base64encode(ptbytes)
key = "im a 16 byte key"
keybytes = stringToBytes(key)
keyhex = bytes2hex(keybytes);
In [ ]:
ct = encryptAES128ECBWithKey(ptb64, keyhex);
In [ ]:
String(base64decode(decryptAES128ECBWithKey(ct, keyhex)))
In [ ]:
ctbytes = encryptAES128ECBWithKey(ptbytes, keybytes);
In [ ]:
String(decryptAES128ECBWithKey(ctbytes, keybytes))
so that works
In [ ]:
function encryptCBCByHand(ptbytes::Array{UInt8,1}, blocksize, ivbytes::Array{UInt8,1}, keybytes::Array{UInt8,1})
cipherbytes = Array{UInt8,1}()
nblocks = convert(Int64, ceil(length(ptbytes)/blocksize))
ptbytes = padToNBytes(ptbytes, blocksize*nblocks)
lastblock = ivbytes
for ii in 1:nblocks
bytestoencrypt = ptbytes[((ii-1)*blocksize+1):(ii*blocksize)] $ lastblock
encryptedbytes = encryptAES128ECBWithKey(bytestoencrypt, keybytes)
append!(cipherbytes, encryptedbytes)
lastblock = encryptedbytes
end
return cipherbytes
end;
In [ ]:
function decryptCBCByHand(ctbytes::Array{UInt8,1}, blocksize, ivbytes::Array{UInt8,1}, keybytes::Array{UInt8,1})
ptbytes = Array{UInt8,1}()
nblocks = convert(Int64, length(ctbytes)/blocksize)
lastblock = ivbytes
for ii in 1:nblocks
bytestodecrypt = ctbytes[((ii-1)*blocksize+1):(ii*blocksize)]
decryptedbytes = decryptAES128ECBWithKey(bytestodecrypt, keybytes) $ lastblock
append!(ptbytes, decryptedbytes)
lastblock = bytestodecrypt
end
return ptbytes
end;
In [ ]:
keybytes = stringToBytes("YELLOW SUBMARINE")
ivbytes = zeros(UInt8, length(keybytes));
ptbytes = stringToBytes("this is just a test to see if this cbc stuff could possibly be right")
blocksize = 16;
In [ ]:
ctattempt = encryptCBCByHand(ptbytes, blocksize, ivbytes, keybytes);
In [ ]:
ctattempt
In [ ]:
decryptattempt = decryptCBCByHand(ctattempt, blocksize, ivbytes, keybytes);
In [ ]:
decryptattempt
In [ ]:
String(decryptattempt)
whoah
In [ ]:
ctb64 = chomp(readstring("10.txt"));
ctbytes = base64decode(ctb64);
keytext = "YELLOW SUBMARINE"
keybytes = stringToBytes(keytext)
ivbytes = zeros(UInt8, length(keybytes));
blocksize = 16;
In [ ]:
decryptattempt = decryptCBCByHand(ctbytes, blocksize, ivbytes, keybytes);
In [ ]:
String(decryptattempt)